#include <QtCore/QSocketNotifier>

#include "bonjourservicebrowser.h"


BonjourServiceBrowser::BonjourServiceBrowser(QWidget *parent) : QTreeWidget(parent)
{
	dnssref = NULL;
	bonjourSocket = NULL;
}

BonjourServiceBrowser::~BonjourServiceBrowser()
{
	// Deallocate bonjour reference if it exists.
	if (dnssref)
	{
		DNSServiceRefDeallocate(dnssref);

		dnssref = NULL;
	}
}

/** Search for bonjour services with identifier string. */
void BonjourServiceBrowser::browseForServiceType(const QString serviceType)
{
	// Browse a service.
	DNSServiceErrorType err = DNSServiceBrowse(&dnssref, 0, 0,
						   serviceType.toUtf8().constData(), 0,
						   bonjourBrowseReply, this);

	// Check errors.
	if (err != kDNSServiceErr_NoError)
		emit error(err);

	else
	{
		int sockfd = DNSServiceRefSockFD(dnssref);

		if (sockfd == -1)
			emit error(kDNSServiceErr_Invalid);

		// Notify that we can now contact the server and read any info from it.
		else
		{
			bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);

			connect(bonjourSocket, SIGNAL(activated(int)),
				this, SLOT(bonjourSocketReadyRead()));
		}
	}
}

void BonjourServiceBrowser::bonjourSocketReadyRead()
{
	DNSServiceErrorType err = DNSServiceProcessResult(dnssref);

	if (err != kDNSServiceErr_NoError)
		emit error(err);
}

void BonjourServiceBrowser::bonjourBrowseReply(DNSServiceRef, DNSServiceFlags flags,
					       quint32, DNSServiceErrorType errorCode,
					       const char *serviceName, const char *regType,
					       const char *replyDomain, void *context)
{
	BonjourServiceBrowser *serviceBrowser = static_cast<BonjourServiceBrowser *>(context);

	if (errorCode != kDNSServiceErr_NoError)
		emit serviceBrowser->error(errorCode);

	else
	{
		BonjourRecord bonjourRecord(serviceName, regType, replyDomain);

		if (flags & kDNSServiceFlagsAdd)
		{
			if (!serviceBrowser->bonjourRecords.contains(bonjourRecord))
				serviceBrowser->bonjourRecords.append(bonjourRecord);
		}

		else
			serviceBrowser->bonjourRecords.removeAll(bonjourRecord);

		if (!(flags & kDNSServiceFlagsMoreComing))
			emit serviceBrowser->currentBonjourRecordsChanged(
					serviceBrowser->bonjourRecords);
	}
}
